package com.tang.core.config;

import com.tang.core.annotation.Select;
import lombok.extern.slf4j.Slf4j;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

/**
 * 代理类定义
 *
 * @param <T>
 * @author tang
 */
@Slf4j
public class MapperFactoryBean<T> implements FactoryBean<T> {

    private final Class<T> mapperInterface;

    private final Map<String, String> data = new HashMap<>();

    // 还有最上面我们提供构造函数来透传需要被代理类，Class<T> mapperInterface，在mybatis中也是使用这样的方式进行透传。
    public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
        data.put("00001", "张三");
        data.put("00002", "李四");
    }

    // 提供类的代理以及模拟对sql语句的处理，这里包含了用户调用dao层方法时候的处理逻辑。
    @Override
    public T getObject() throws Exception {
        // JDK动态代理获取代理对象
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Select select = method.getAnnotation(Select.class);
                log.info("SQL:{}", select.value().replace("#{uId}", args[0].toString()));
                return data.get(args[0].toString());
            }
        };
        return (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{mapperInterface}, invocationHandler);
        
        // CGlIB代理
//        MethodInterceptor methodInterceptor = new MethodInterceptor() {
//            @Override
//            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//                Select select = method.getAnnotation(Select.class);
//                log.info("SQL:{}", select.value().replace("#{uId}", args[0].toString()));
//                return data.get(args[0].toString());
//            }
//        };
//
//
//        // 创建动态代理增强类
//        Enhancer enhancer = new Enhancer();
//        // 设置类加载器
//        enhancer.setClassLoader(this.getClass().getClassLoader());
//        // 设置被代理类
//        enhancer.setSuperclass(mapperInterface);
//        // 设置方法拦截器
//        enhancer.setCallback(methodInterceptor);
//        // 创建代理类
//        return (T) enhancer.create();
    }

    // 提供对象类型反馈
    @Override
    public Class<?> getObjectType() {
        return mapperInterface;
    }

    // isSingleton() 返回类是单例的。
    @Override
    public boolean isSingleton() {
        return true;
    }
    
}
